<?php
/**
 * 框架 - HTTP请求信息处理类
 * 
 * @version $Id: Request.php 202 2011-06-20 08:56:01Z linsir123 $
 */
class Request
{
	/**
	 * @var 请求的域名信息
	 */
	public $domain;
	
	/**
	 * @var 请求路径信息
	 */
	public $path = null;
	
	/**
	 * @var 路由信息
	 */
	public $routes = array();
	
	/**
	 * @var 分析出来请求信息
	 */
	public $parts = array();
	
	/**
	 * 构造函数
	 */
	public function __construct()
	{
		$uri = substr($_SERVER['REQUEST_URI'], 0, strrpos($_SERVER['REQUEST_URI'], '/'));
		$phpSelf = substr($_SERVER['SCRIPT_NAME'], 0, strrpos($_SERVER['SCRIPT_NAME'], '/'));
		if (empty($phpSelf) || strpos($uri, $phpSelf) === false) 
			$phpSelf = '';
			
		$this->domain = htmlspecialchars(preg_replace("/\/+(api|archiver|wap)?\/*$/i", '', $phpSelf) . '/');
	}
	
	/**
	 * 分析请求路径信息
	 */
	private function _initPath()
	{
		$urlModel = App::instance()->urlMode;
		if ($urlModel == URL_PHPINFO && isset($_SERVER['PATH_INFO'])) 
			$this->path = substr($_SERVER['PATH_INFO'], 1);
		elseif ($urlModel == URL_REWRITE && isset($_GET['url'])) 
			$this->path = $_GET['url'];
			
		return isset($this->path);
	}
	
	/**
	 * 分析路由信息
	 */
	private function _initRoute()
	{
		$tmp = array();
		$routes = App::instance()->routes;
		if (is_array($routes) && $routes) {
			foreach ($routes as $r => $route) {
				$keys = array();
				$pattern = $r;
				preg_match_all("/(<(\w+):([^\/]+)>)/", $r, $matches);
				$count = count($matches[0]);
				for ($i = 0; $i < $count; $i++) {
					$keys[] = trim($matches[2][$i]);
					$pattern = str_replace('/'.$matches[1][$i], '\/('.$matches[3][$i].')', $pattern);
				}
				
				$tmp[$r] = array('pattern'=>'/^'.$pattern.'$/i','route'=>$route,'keys'=>$keys);
			}
			
			///
			$this->routes = $tmp;
		}
		
		return true;
	}
	
	/**
	 * 分析请求信息
	 */
	private function _parse()
	{
		foreach ($this->routes as $r) {
			if (preg_match($r['pattern'], $this->path, $matches)) {
				array_shift($matches);
				$this->path = $r['route'];
				foreach ($r['keys'] as $i => $key) 
					$_GET[$key] = $matches[$i];
					
				break;
			}
		}
		
		///
		if ($this->path) {
			if ($this->parts = explode('/', $this->path)) {
				$subApps = App::instance()->subApps;
				$subApps = is_array($subApps) ? array_keys($subApps) : array();
				if (in_array($this->parts[0], $subApps)) 
					App::instance()->setSubApp(array_shift($this->parts));
			}
		}
		
		return true;
	}
	
	/**
	 * 初始化
	 */
	public function init()
	{
		$this->_initPath() and $this->_initRoute() and $this->_parse();
	}
	
	/**
	 * 取得请求信息数组
	 */
	public function getParts()
	{
		return $this->parts;
	}
	
	
	/// 以下方法提供为静态调用  ///
	
	
	/**
	 * 判断HTTP请求是否是POST方法
	 */
	static function isPost()
	{
		return strtoupper($_SERVER['REQUEST_METHOD']) == 'POST';
	}
	
	/**
	 * 判断HTTP请求是否是通过XMLHttp发起的
	 */
	static function isAjax()
	{
		$r = isset($_SERVER['HTTP_X_REQUESTED_WITH']) ? strtoupper($_SERVER['HTTP_X_REQUESTED_WITH']) : '';
		return $r == 'XMLHTTPREQUEST';
	}
	
	/**
	 * 返回客户端IP地址
	 */
	static function ip()
	{
		if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) 
			$onlineip = getenv('HTTP_CLIENT_IP');
		elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) 
			$onlineip = getenv('HTTP_X_FORWARDED_FOR');
		elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) 
			$onlineip = getenv('REMOTE_ADDR');
		elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) 
			$onlineip = $_SERVER['REMOTE_ADDR'];
		
		preg_match("/[\d\.]{7,15}/", $onlineip, $onlineipmatches);
		$onlineip = $onlineipmatches[0] ? $onlineipmatches[0] : 'unknown';
		
		return $onlineip;
	}
}
